//
//  YXPlayerResourceLoaderManager.swift
//  swift_wobo
//
//  Created by yuxin on 2018/12/2.
//  Copyright © 2018 wuxiantianli. All rights reserved.
//

import UIKit
import AVFoundation

class YXPlayerResourceLoaderManager: NSObject {
    
    private let kCacheScheme = "__YXPlayerMideaCache__"
    private var loaderDict = [String: YXPlayerResourceLoader]()
    
    func customPlayerItem(_ url: URL) -> AVPlayerItem {
        let newUrl = customURL(url)
        let urlAsset = AVURLAsset(url: newUrl, options: nil)
        urlAsset.resourceLoader.setDelegate(self, queue: DispatchQueue.main)
        let playerItem = AVPlayerItem(asset: urlAsset)
        if #available(iOS 9.0, *) {
            playerItem.canUseNetworkResourcesForLiveStreamingWhilePaused = true
        }
        return playerItem
    }

}


// MARK: - helper
extension YXPlayerResourceLoaderManager {
    private func customURL(_ url: URL) -> URL {
        let customUrlStr = kCacheScheme + url.absoluteString
        let customUrl = URL(string: customUrlStr)
        return customUrl!
    }
    
    private func loaderObtainByCache(loadingRequest: AVAssetResourceLoadingRequest) -> YXPlayerResourceLoader? {
        guard let requestKey = checkUrlKey(url: loadingRequest.request.url!)  else {
            return nil
        }
        let loader = loaderDict[requestKey]
        return loader
    }
    
    private func checkUrlKey(url : URL) -> String? {
        guard url.absoluteString.hasPrefix(kCacheScheme) else { return nil}
        return url.absoluteString
    }
    
}

// MARK: - AVAssetResourceLoaderDelegate
//https://www.jianshu.com/p/c157476474f1 多次调用
/*
 设置请求range
 NSString *range = [NSString stringWithFormat:@"bytes=%lld-%lld", fromOffset, endOffset];
 [request setValue:range forHTTPHeaderField:@"Range"];
 1、不处理，大约两次。第一次：0-2，第二次2-end
 2、设置上面的第二次
 
 */

extension YXPlayerResourceLoaderManager: AVAssetResourceLoaderDelegate {
    func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
        
        
        if let resourceUrl = loadingRequest.request.url, resourceUrl.absoluteString.hasPrefix(kCacheScheme) {
            var loader = loaderObtainByCache(loadingRequest: loadingRequest)
            if loader == nil {
                let originUrlStr = resourceUrl.absoluteString.replacingOccurrences(of: kCacheScheme, with: "")
                let originUrl = URL(string: originUrlStr)!
                loader = YXPlayerResourceLoader(url: originUrl)
                loader?.delegate = self
                let key = checkUrlKey(url: resourceUrl)!
                loaderDict[key] = loader
            }
            loader?.append(loadingRequest: loadingRequest)
            print("========================================2")
            return true
        }
        
        return false
    }
    
    func resourceLoader(_ resourceLoader: AVAssetResourceLoader, didCancel loadingRequest: AVAssetResourceLoadingRequest) {
        let loader = loaderObtainByCache(loadingRequest: loadingRequest)
        loader?.cancel()
        loader?.remove(loadingRequest: loadingRequest)
    }
    
}


// MARK: - YXPlayerResourceLoaderDelegate
extension YXPlayerResourceLoaderManager: YXPlayerResourceLoaderDelegate {
    func playerResourceLoader(_ loader: YXPlayerResourceLoader, didCompleteWithError error: Error?) {
        print(error?.localizedDescription as Any)
    }
    
}
